﻿using SketchUpAPI.NET.Enums;
using SketchUpAPI.NET.SketchUp.Exception;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace SketchUpAPI.NET.Objects.Tables
{
    /// <summary>
    /// 材质表
    /// </summary>
    /// <remarks>该类型不是 SketchUpAPI 中的类型，而是为了方便管理材质添加的类型，该类型的 Id 使用的是 <see cref="SketchUp.SketchUpModel"/> 的 Id </remarks>
    public class MaterialTable : ObjectBase
    {
        #region API 函数
        /// <summary>
        /// 材质总数
        /// </summary>
        /// <param name="model"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUModelGetNumMaterials(IntPtr model, out long count);

        /// <summary>
        /// 获取全部材质
        /// </summary>
        /// <param name="model"></param>
        /// <param name="len"></param>
        /// <param name="materials"><see cref="Material"/>[]</param>
        /// <param name="realCount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUModelGetMaterials(IntPtr model, int len, IntPtr[] materials, out int realCount);

        /// <summary>
        /// 添加材质
        /// </summary>
        /// <param name="model"></param>
        /// <param name="len"></param>
        /// <param name="materials"><see cref="Material"/>[]</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUModelAddMaterials(IntPtr model, int len, IntPtr[] materials);

        /// <summary>
        /// 删除材质
        /// </summary>
        /// <param name="model"></param>
        /// <param name="len"></param>
        /// <param name="materials"><see cref="Objects.Material"/>[]</param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUModelRemoveMaterials(IntPtr model, int len, IntPtr[] materials);

        /// <summary>
        /// 获取材质个数
        /// </summary>
        /// <remarks>包括 <see cref="Image"/> 和 <see cref="Layer"/> 的材质</remarks>
        /// <param name="model"></param>
        /// <param name="count"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUModelGetNumAllMaterials(IntPtr model, out int count);

        /// <summary>
        /// 获取所有材质
        /// </summary>
        /// <remarks>包括 <see cref="Image"/> 和 <see cref="Layer"/> 的材质</remarks>
        /// <param name="model"></param>
        /// <param name="len"></param>
        /// <param name="materials"><see cref="Objects.Material"/>[]</param>
        /// <param name="realcount"></param>
        /// <returns></returns>
        [DllImport(LIB)]
        static extern SUResult SUModelGetAllMaterials(IntPtr model, int len, IntPtr[] materials, out int realcount);
        #endregion

        /// <summary>
        /// 材质总数
        /// </summary>
        public int Count
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUModelGetNumMaterials(Id, out long count));
                return (int)count;
            }
        }

        public List<Material> Materials
        {
            get
            {
                IntPtr[] ptrs = new IntPtr[Count];
                SketchUpExceptionHelper.ThrowSUResult(SUModelGetMaterials(Id, Count, ptrs, out int realCount));
                return ptrs.Select(pt => new Material(pt)).ToList();
            }
        }

        /// <summary>
        /// 全部材质，包括 <see cref="Image"/> 和 <see cref="Layer"/> 的材质
        /// </summary>
        public List<Material> AllMaterials
        {
            get
            {
                SketchUpExceptionHelper.ThrowSUResult(SUModelGetNumAllMaterials(Id, out int c));
                IntPtr[] pts = new IntPtr[c];
                SketchUpExceptionHelper.ThrowSUResult(SUModelGetAllMaterials(Id, c, pts, out _));
                return pts.Select(i => new Material(i)).ToList();
            }
        }

        internal MaterialTable(IntPtr id)
        {
            Id = id;
        }

        /// <summary>
        /// 添加材质
        /// </summary>
        /// <param name="materials"></param>
        public void Add(params Material[] materials)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUModelAddMaterials(Id, materials.Length, materials.Select(m => m.Id).ToArray()));
        }

        /// <summary>
        /// 删除材质
        /// </summary>
        /// <param name="materials"></param>
        public void Remove(params Material[] materials)
        {
            SketchUpExceptionHelper.ThrowSUResult(SUModelRemoveMaterials(Id, materials.Length, materials.Select(m => m.Id).ToArray()));
        }
    }
}